package cn.good.yan.config.filters;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import java.net.URI;

/**
 * 自定义过滤器 （单一过滤器）
 * <p>
 * 路由配置需要
 * # 授权服务1
 * - id: auth9002
 * uri: lb://auth9002
 * predicates:
 * - Path=/auth9002/**
 * filters:
 * - StripPrefix=1
 * - Validate       # 单一过滤器 （可以没有参数，参数在Config里配置）
 *
 * 测试：
 * 访问： http://localhost:8080/auth9002/hello  （通过）
 * 访问： http://localhost:8080/auth9002/xxx    （不通过）
 * @author shengren.yan
 * @create 2024/11/21
 */
@Component
@Slf4j
public class ValidateGatewayFilterFactory
        extends AbstractGatewayFilterFactory<ValidateGatewayFilterFactory.Config> {

    public ValidateGatewayFilterFactory() {
        super(Config.class);
    }


    /**
     * 定义请求过滤器
     *
     * @param config
     * @return {@code GatewayFilter}
     */
    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {

            // 获取请求路径
            String path = exchange.getRequest().getPath().toString();  // 相对路径
            // 全路径的url
            URI uri = exchange.getRequest().getURI();
            System.err.println(String.format("获取到请求路径：%s", uri.toString()));

            if (StringUtils.isNotEmpty(path)) {
                if (path.contains("/login") ||
                        path.contains("/logout") ||
                        path.contains("/capt") ||
                        path.contains("/hello")) {
                    // 放行
                    return chain.filter(exchange);
                } else {
                    // 返回410，进行拦截，不放行
                    exchange.getResponse().setStatusCode(HttpStatus.GONE);
                    return exchange.getResponse().setComplete();
                }
            }
            // 继续执行过滤器链
            return chain.filter(exchange);
        };
    }

    // 配置类，属性用于接收配置文件中的值
    public static class Config {

    }


}
